'use strict';
const EventEmitter = require('events');
const fiip = require('fiip');
const listeners = require('./listeners.js');
const cloudVar = require('./var.js');

const cmd = {
  getId: 0x7011,
  login: 0x7012,
  heart: 0x7013,
  bind: 0x7014,
  unbind: 0x7015,
  enterBinding: 0x7016,
  setActualVar: 0x7021,
  getActualVar: 0x7022,
  subActualVar: 0x7023,
  getActualAllVar: 0x7024,
  subActualAllVar: 0x7025,
  setTargetVar: 0x7029,
  getTargetVar: 0x702a,
  subTargetVar: 0x702b,
  getTargetAllVar: 0x702c,
  subTargetAllVar: 0x702d,
};
const event = {
  getId: 0xf011,
  login: 0xf012,
  heart: 0xf013,
  bind: 0xf014,
  unbind: 0xf015,
  enterBinding: 0xf016,
  beBound: 0x7811,
  beUnbound: 0x7812,
  setActualVar: 0xf021,
  getActualVar: 0xf022,
  subActualVar: 0xf023,
  getActualAllVar: 0xf024,
  subActualAllVar: 0xf025,
  setTargetVar: 0xf029,
  getTargetVar: 0xf02a,
  subTargetVar: 0xf02b,
  getTargetAllVar: 0xf02c,
  subTargetAllVar: 0xf02d,
  error: 0xffff,
};

function cvtCmd(cmd) {
  const cmdBuf = Buffer.alloc(2);
  cmdBuf[0] = cmd >> 8;
  cmdBuf[1] = cmd;
  return cmdBuf;
}

class Cloud extends EventEmitter {
  constructor() {
    super();
    this.event = event;
    this.vars = cloudVar;
    this.myId = null;
    this.myKey = null;
    this.txd = null;
    this.link = null;
    this.cmd_body = null;
  }
  init(id, key) {
    this.myId = id;
    this.myKey = key;
    this.txd = new fiip.Format();
    if (this.link == null) this.link = fiip.route.find(fiip.centerId);
    if (this.link == null) console.error('Please connect cloud.');

    this.vars.init();
    listeners.start(this);
  }
  getId(typeId, typeKey) {
    this.cmd_body = Buffer.concat([typeId, typeKey]);
    this.txd.setVar('cmd', cvtCmd(cmd.getId), 2);
    this.txd.setVar('body', this.cmd_body, 8);
    fiip.request(this.txd, fiip.centerId, this.link);
  }
  login() {
    this.txd.setVar('cmd', cvtCmd(cmd.login), 2);
    this.txd.setVar('body', this.myKey, 4);
    fiip.request(this.txd, fiip.centerId, this.link);
  }
  heart() {
    this.txd.setVar('cmd', cvtCmd(cmd.heart), 2);
    this.txd.setVar('body', this.myKey, 4);
    fiip.request(this.txd, fiip.centerId, this.link);
  }
  bind(typeId, code) {
    this.cmd_body = Buffer.concat([typeId, code]);
    this.txd.setVar('cmd', cvtCmd(cmd.bind), 2);
    this.txd.setVar('body', this.cmd_body, 8);
    fiip.request(this.txd, fiip.centerId, this.link);
  }
  unbind(id) {
    this.txd.setVar('cmd', cvtCmd(cmd.unbind), 2);
    this.txd.setVar('body', id, 8);
    fiip.request(this.txd, fiip.centerId, this.link);
  }
  enterBinding(code) {
    this.txd.setVar('cmd', cvtCmd(cmd.enterBinding), 2);
    this.txd.setVar('body', code, 4);
    fiip.request(this.txd, fiip.centerId, this.link);
  }
  setActualVar(id, key, kVal, kLen, vVal, vLen) {
    this.vars.setActual(id, kVal, kLen, vVal, vLen);
    this.cmd_body = Buffer.concat([id, key, Buffer.alloc(1, kLen), kVal, Buffer.alloc(1, vLen), vVal]);
    this.txd.setVar('cmd', cvtCmd(cmd.setActualVar), 2);
    this.txd.setVar('body', this.cmd_body, 14 + kLen + vLen);
    fiip.request(this.txd, fiip.centerId, this.link);
  }
  getActualVar(id, key, kVal, kLen) {
    this.cmd_body = Buffer.concat([id, key, Buffer.alloc(1, kLen), kVal]);
    this.txd.setVar('cmd', cvtCmd(cmd.getActualVar), 2);
    this.txd.setVar('body', this.cmd_body, 13 + kLen);
    fiip.request(this.txd, fiip.centerId, this.link);
  }
  subActualVar(id, key, kVal, kLen) {
    this.cmd_body = Buffer.concat([id, key, Buffer.alloc(1, kLen), kVal]);
    this.txd.setVar('cmd', cvtCmd(cmd.subActualVar), 2);
    this.txd.setVar('body', this.cmd_body, 13 + kLen);
    fiip.request(this.txd, fiip.centerId, this.link);
  }
  getActualAllVar(id, key) {
    this.cmd_body = Buffer.concat([id, key]);
    this.txd.setVar('cmd', cvtCmd(cmd.getActualAllVar), 2);
    this.txd.setVar('body', this.cmd_body, 12);
    fiip.request(this.txd, fiip.centerId, this.link);
  }
  subActualAllVar(id, key) {
    this.cmd_body = Buffer.concat([id, key, Buffer.alloc(1, 0)]);
    this.txd.setVar('cmd', cvtCmd(cmd.subActualAllVar), 2);
    this.txd.setVar('body', this.cmd_body, 13);
    fiip.request(this.txd, fiip.centerId, this.link);
  }
  setTargetVar(id, key, kVal, kLen, vVal, vLen) {
    this.vars.setTarget(id, kVal, kLen, vVal, vLen);
    this.cmd_body = Buffer.concat([id, key, Buffer.alloc(1, kLen), kVal, Buffer.alloc(1, vLen), vVal]);
    this.txd.setVar('cmd', cvtCmd(cmd.setTargetVar), 2);
    this.txd.setVar('body', this.cmd_body, 14 + kLen + vLen);
    fiip.request(this.txd, fiip.centerId, this.link);
  }
  getTargetVar(id, key, kVal, kLen) {
    this.cmd_body = Buffer.concat([id, key, Buffer.alloc(1, kLen), kVal]);
    this.txd.setVar('cmd', cvtCmd(cmd.getTargetVar), 2);
    this.txd.setVar('body', this.cmd_body, 1 + kLen);
    fiip.request(this.txd, fiip.centerId, this.link);
  }
  subTargetVar(id, key, kVal, kLen) {
    this.cmd_body = Buffer.concat([id, key, Buffer.alloc(1, kLen), kVal]);
    this.txd.setVar('cmd', cvtCmd(cmd.subTargetVar), 2);
    this.txd.setVar('body', this.cmd_body, 13 + kLen);
    fiip.request(this.txd, fiip.centerId, this.link);
  }
  getTargetAllVar(id, key) {
    this.cmd_body = Buffer.concat([id, key]);
    this.txd.setVar('cmd', cvtCmd(cmd.getTargetAllVar), 2);
    this.txd.setVar('body', this.cmd_body, 12);
    fiip.request(this.txd, fiip.centerId, this.link);
  }
  subTargetAllVar(id, key) {
    this.cmd_body = Buffer.concat([id, key, Buffer.alloc(1, 0)]);
    this.txd.setVar('cmd', cvtCmd(cmd.subTargetAllVar), 2);
    this.txd.setVar('body', this.cmd_body, 13);
    fiip.request(this.txd, fiip.centerId, this.link);
  }
}

const cloud = new Cloud();
module.exports = cloud;
